home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Samples / SampleCode / BoxPaint+ - non stereo / sources / BoxPaint_cursor3d.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-14  |  29.1 KB  |  1,126 lines  |  [TEXT/CWIE]

  1. /******************************************************************************
  2.  **                                                                             **
  3.  **     Module:        BoxPaint_cursor3d.c                                         **
  4.  **                                                                          **
  5.  **                                                                          **
  6.  **     Purpose:     Contains code to create and manipulate a 3D cursor.         **
  7.  **                                                                          **
  8.  **     Author:        Michael Bishop                                             **
  9.  **                                                                          **
  10.  **                                                                          **
  11.  **     Copyright (C) 1996-1997 Apple Computer, Inc.  All rights reserved.     **
  12.  **                                                                          **
  13.  **                                                                          **
  14.  *****************************************************************************/
  15.  
  16. #include    <Memory.h>
  17. #include    <assert.h>
  18.  
  19. #include    "QD3D.h"
  20. #include    "QD3DGroup.h"
  21. #include    "QD3DGeometry.h"
  22. #include    "QD3DMath.h"
  23. #include    "QD3DTransform.h"
  24. #include    "QD3DShader.h"
  25.  
  26. #include    "BoxPaint_cursor3d.h"
  27. #include    "BoxPaint_Support.h"
  28. #include    "BoxPaint_utility.h"
  29.  
  30.  
  31. /******************************************************************************
  32.  **                                                                             **
  33.  **                                STRUCTURES                                     **
  34.  **                                                                             **
  35.  **        Comments:    IF YOU CHANGE THIS, UPDATE Cursor3D_Init, _Dispose,         **
  36.  **                    and_New !!!!!!!!!!!                                      **
  37.  **                                                                             **
  38.  *****************************************************************************/
  39.  
  40. struct _cursor3d    {
  41.     TQ3Boolean            fShowOrientation;    /*    to show the direction the
  42.                                                     cursor is pointing    */
  43.     TQ3GroupObject        fCursorModel;        /*    the Cursor Shape    */
  44.     TQ3GroupObject        fOrientationModel;    /*    the orientation indicator*/
  45.     Cursor3DPlacement    fCursorPlacement;    /*    Where is the cursor?    */
  46.     TQ3Matrix4x4        fTransform;            /*    Local to World space    */
  47.     TQ3Vector3D            fScale;                /*    the relative size    */
  48.     TQ3AttributeSet        fCursorAttributeSet;/*    Attributes for the whole
  49.                                                     cursor    */
  50. } ;
  51.  
  52. /******************************************************************************
  53.  **                                                                             **
  54.  **                            Local functions                                     **
  55.  **                                                                             **
  56.  *****************************************************************************/
  57.  
  58. static void    Cursor3D_Init(
  59.     Cursor3DHdl         theCursor3D);
  60.     
  61. static void    Cursor3D_InitPlacement(
  62.     Cursor3DPlacement    *theCursor3DPlacement);
  63.     
  64. static void    Cursor3D_EnableBounding(
  65.     Cursor3DHdl            theCursor3D);
  66.     
  67. static void    Cursor3D_DisableBounding(
  68.     Cursor3DHdl            theCursor3D);
  69.     
  70. static void    Cursor3D_Scale(
  71.     Cursor3DHdl            theCursor3D,
  72.     float theScale);
  73.  
  74. static TQ3DisplayGroupObject    Cursor3D_NewDefaultCursor(
  75.     void);
  76.     
  77. static TQ3DisplayGroupObject    Cursor3D_NewDefaultOrientationModel(
  78.     void);
  79.     
  80.  
  81. /*===========================================================================*\
  82.  *
  83.  *    Routine:    Cursor3D_New()
  84.  *
  85.  *    Comments:    
  86.  *
  87. \*===========================================================================*/
  88.  
  89. Cursor3DHdl    Cursor3D_New(TQ3GroupObject theModel)
  90. {
  91.     Cursor3DHdl                theCursor3D;
  92.     TQ3DisplayGroupState    theState;
  93.     TQ3ColorRGB                theColor;
  94.  
  95.     /*
  96.     **    Allocate the memory
  97.     */
  98.     
  99.     if (( theCursor3D = (Cursor3DHdl)Utility_MemoryNew(sizeof(Cursor3D))) != NULL)
  100.     {
  101.         Cursor3D_Init(theCursor3D);
  102.         
  103.         
  104.         /**************************************
  105.          **                                     **
  106.          **            fCursorModel             **
  107.          **                                     **
  108.          **************************************/
  109.         
  110.         /*
  111.         **    If we were passed in a model
  112.         */
  113.         
  114.         if ( theModel != NULL )
  115.         {
  116.             /*    
  117.             **    Add it to our group
  118.             **    NOTE: we add it instead of assigning it to fCursorModel
  119.             **    because we may want to set flags or otherwise affect our
  120.             **    group object without affecting the original, passed-in model
  121.             */    
  122.  
  123.             /*
  124.             **    Allocate the cursor
  125.             */
  126.             (**theCursor3D).fCursorModel = Q3DisplayGroup_New();
  127.             if ((**theCursor3D).fCursorModel == NULL)
  128.                 goto bail;
  129.                 
  130.             if ( Q3Group_AddObject((**theCursor3D).fCursorModel, theModel) != NULL )
  131.                 goto bail;
  132.         }
  133.         /*
  134.         **    Otherwise, add our default model
  135.         */
  136.         
  137.         else {
  138.             (**theCursor3D).fCursorModel = Cursor3D_NewDefaultCursor();
  139.             if ((**theCursor3D).fCursorModel == NULL)
  140.                 goto bail;
  141.         }
  142.         
  143.         /*    
  144.         **    We want to set some state variables for the cursor so get
  145.         **    the state of the fCursorModel so we can preserve whatever's
  146.         **     already there
  147.         */    
  148.         Q3DisplayGroup_GetState((**theCursor3D).fCursorModel, &theState);
  149.         
  150.         /*
  151.         **    we don't want the cursor to be picked
  152.         */
  153.             
  154.         theState = theState & ~(kQ3DisplayGroupStateMaskIsPicked);
  155.         
  156.         /*    
  157.         **    We inline the cursor because the group is basically just
  158.         **    being used to hold geometries and not attributes. When a
  159.         **    group is submitted, the stack is pushed and then popped
  160.         **    afterwards. Since there is no reason for us to push and pop
  161.         **    the stack, we inline it, which prevents that from occurring.
  162.         **    Keep in mind that any attributes in this group will be held
  163.         **    over for the next group (ie. any thing submitted after the
  164.         **    cursor will be transparent unless the stack is popped
  165.         */
  166.         theState = theState | (kQ3DisplayGroupStateMaskIsInline);
  167.                                 
  168.         Q3DisplayGroup_SetState((**theCursor3D).fCursorModel,  theState);
  169.         
  170.         
  171.         
  172.         
  173.         /**************************************
  174.          **                                     **
  175.          **            fOrientationModel         **
  176.          **                                     **
  177.          **************************************/
  178.         
  179.         /*
  180.         **    Allocate the orientation
  181.         */
  182.         (**theCursor3D).fOrientationModel = Cursor3D_NewDefaultOrientationModel();
  183.         if ((**theCursor3D).fOrientationModel != NULL)
  184.         {
  185.             /*    
  186.             **    Don't bail, we can live with no orientation model
  187.             **    Now, get the state of the orientation model
  188.             */
  189.             
  190.             Q3DisplayGroup_GetState((**theCursor3D).fOrientationModel, &theState);
  191.             
  192.             /*    
  193.             **    we don't want the orientation to be picked
  194.             */
  195.                 
  196.             theState = theState & ~(kQ3DisplayGroupStateMaskIsPicked);
  197.             theState = theState | (kQ3DisplayGroupStateMaskIsInline);
  198.                                     
  199.             Q3DisplayGroup_SetState((**theCursor3D).fOrientationModel,  theState);
  200.             
  201.         }
  202.         
  203.         
  204.         /**************************************
  205.          **                                     **
  206.          **        fCursorAttributeSet             **
  207.          **                                     **
  208.          **************************************/
  209.  
  210.         /*
  211.         **    Make the cursor transparent
  212.         */
  213.         (**theCursor3D).fCursorAttributeSet = Q3AttributeSet_New ();
  214.         
  215.         if ((**theCursor3D).fCursorAttributeSet != NULL)
  216.         {
  217.             theColor.r = theColor.g = theColor.b = 0.35 ;
  218.  
  219.             Q3AttributeSet_Add ((**theCursor3D).fCursorAttributeSet,
  220.                                 kQ3AttributeTypeTransparencyColor,
  221.                                 &theColor);
  222.         }
  223.         
  224.         
  225.         /*
  226.         **    Finally, we don't want the cursor to be included in bounding
  227.         **    operations
  228.         */
  229.         Cursor3D_DisableBounding(theCursor3D);
  230.         
  231.     }
  232.     
  233.     return theCursor3D;
  234.     
  235. bail:
  236.     Cursor3D_Dispose(theCursor3D);
  237.     return NULL;
  238.     
  239. }
  240.  
  241.  
  242. /*===========================================================================*\
  243.  *
  244.  *    Routine:    Cursor3D_Dispose()
  245.  *
  246.  *    Comments:    Cleans up and deallocates memory.
  247.  *
  248. \*===========================================================================*/
  249.  
  250. TQ3Status    Cursor3D_Dispose(Cursor3DHdl theCursor3D)
  251. {
  252.     assert(theCursor3D != NULL);
  253.     assert(*theCursor3D != NULL);
  254.  
  255.     if ((**theCursor3D).fCursorModel != NULL)
  256.         Q3Object_Dispose((**theCursor3D).fCursorModel);
  257.                 
  258.     if ((**theCursor3D).fOrientationModel != NULL)
  259.         Q3Object_Dispose((**theCursor3D).fOrientationModel);
  260.         
  261.     if ((**theCursor3D).fCursorAttributeSet != NULL)
  262.         Q3Object_Dispose((**theCursor3D).fCursorAttributeSet);
  263.     
  264.     DisposeHandle((Handle)theCursor3D);
  265.                 
  266.     return kQ3Success;
  267. }
  268.  
  269.  
  270. /*===========================================================================*\
  271.  *
  272.  *    Routine:    Cursor3D_Show()
  273.  *
  274.  *    Comments:    
  275.  *
  276. \*===========================================================================*/
  277.  
  278. void    Cursor3D_Show(Cursor3DHdl theCursor3D)
  279. {
  280.     TQ3DisplayGroupState    theState;
  281.     
  282.     assert(theCursor3D != NULL);
  283.     assert(*theCursor3D != NULL);
  284.  
  285.     /*
  286.     **    Get the original Flags
  287.     */
  288.     Q3DisplayGroup_GetState((**theCursor3D).fCursorModel, &theState);
  289.     
  290.     /*
  291.     **    we want the cursor to be drawn
  292.     */
  293.     theState = theState | (    kQ3DisplayGroupStateMaskIsDrawn);
  294.  
  295.      Q3DisplayGroup_SetState((**theCursor3D).fCursorModel,  theState);
  296.  
  297.     /*
  298.     **    Same thing for fOrientationModel
  299.     */
  300.     Q3DisplayGroup_GetState((**theCursor3D).fOrientationModel, &theState);
  301.     theState = theState | (    kQ3DisplayGroupStateMaskIsDrawn);
  302.      Q3DisplayGroup_SetState((**theCursor3D).fOrientationModel,  theState);
  303. }
  304.  
  305.  
  306. /*===========================================================================*\
  307.  *
  308.  *    Routine:    Cursor3D_Hide()
  309.  *
  310.  *    Comments:    
  311.  *
  312. \*===========================================================================*/
  313.  
  314. void    Cursor3D_Hide(Cursor3DHdl theCursor3D)
  315. {
  316.     TQ3DisplayGroupState    theState;
  317.     
  318.     assert(theCursor3D != NULL);
  319.     assert(*theCursor3D != NULL);
  320.  
  321.     /*
  322.     **    See Cursor3D_Show
  323.     */
  324.     Q3DisplayGroup_GetState((**theCursor3D).fCursorModel,  &theState);
  325.     theState = theState & ~(kQ3DisplayGroupStateMaskIsDrawn);
  326.      Q3DisplayGroup_SetState((**theCursor3D).fCursorModel,  theState);
  327.     
  328.     Q3DisplayGroup_GetState((**theCursor3D).fOrientationModel,  &theState);
  329.     theState = theState & ~(kQ3DisplayGroupStateMaskIsDrawn);
  330.      Q3DisplayGroup_SetState((**theCursor3D).fOrientationModel,  theState);
  331. }
  332.  
  333.  
  334. /*===========================================================================*\
  335.  *
  336.  *    Routine:    Cursor3D_SetPlacement()
  337.  *
  338.  *    Comments:    Sets the Cursor to whereever you want. Input MUST be
  339.  *    normalized
  340.  *
  341. \*===========================================================================*/
  342.  
  343. TQ3Status    Cursor3D_SetPlacement(
  344.     Cursor3DHdl            theCursor3D,
  345.     Cursor3DPlacement    *theCursor3DPlacement) 
  346. {
  347.     TQ3Matrix4x4    theMatrix4x4;
  348.     TQ3Vector3D        theXAxis;
  349.     
  350.     assert(theCursor3D != NULL);
  351.     assert(*theCursor3D != NULL);
  352.  
  353.     Q3Matrix4x4_SetIdentity(&theMatrix4x4);
  354.     
  355.     /*
  356.     **    Get the last vector we need
  357.     */
  358.     Q3Vector3D_Cross(    (const TQ3Vector3D *)&theCursor3DPlacement->up,
  359.                         (const TQ3Vector3D *) &theCursor3DPlacement->toward,
  360.                         &theXAxis);
  361.  
  362.     /*
  363.     **    This is a neat graphics trick stuff the normals into the matrix and
  364.     **    it will automatically place your cursor with all the correct
  365.     **    orientation
  366.     */
  367.  
  368.     theMatrix4x4.value[0][0] = theXAxis.x;
  369.     theMatrix4x4.value[0][1] = theXAxis.y;
  370.     theMatrix4x4.value[0][2] = theXAxis.z;
  371.     
  372.     theMatrix4x4.value[1][0] = theCursor3DPlacement->up.x;
  373.     theMatrix4x4.value[1][1] = theCursor3DPlacement->up.y;
  374.     theMatrix4x4.value[1][2] = theCursor3DPlacement->up.z;
  375.  
  376.     theMatrix4x4.value[2][0] = theCursor3DPlacement->toward.x;
  377.     theMatrix4x4.value[2][1] = theCursor3DPlacement->toward.y;
  378.     theMatrix4x4.value[2][2] = theCursor3DPlacement->toward.z;
  379.     
  380.     /*
  381.     **    Stuff in the translation too
  382.     */
  383.     theMatrix4x4.value[3][0] = theCursor3DPlacement->cursorLocation.x;
  384.     theMatrix4x4.value[3][1] = theCursor3DPlacement->cursorLocation.y;
  385.     theMatrix4x4.value[3][2] = theCursor3DPlacement->cursorLocation.z;
  386.  
  387.     (**theCursor3D).fTransform = theMatrix4x4;
  388.     
  389.     return kQ3Success;
  390.     
  391. }
  392.  
  393.  
  394. /*===========================================================================*\
  395.  *
  396.  *    Routine:    Cursor3D_Submit()
  397.  *
  398.  *    Comments:    
  399.  *
  400. \*===========================================================================*/
  401.  
  402. TQ3Status    Cursor3D_Submit(
  403.     Cursor3DPtr        theCursor3D,
  404.     TQ3ViewObject    theView)
  405. {
  406.     assert(theCursor3D != NULL);
  407.     
  408.     if (
  409.         Q3AttributeSet_Submit ( theCursor3D->fCursorAttributeSet, theView )
  410.         == kQ3Failure) goto bail;
  411.         
  412.     if(
  413.         Q3MatrixTransform_Submit( &theCursor3D->fTransform, theView)
  414.         == kQ3Failure) goto bail;
  415.         
  416.     if (
  417.         Q3ScaleTransform_Submit ( &theCursor3D->fScale, theView )
  418.         == kQ3Failure) goto bail;
  419.         
  420.     if (
  421.         Q3DisplayGroup_Submit( theCursor3D->fOrientationModel, theView)
  422.         == kQ3Failure) goto bail;
  423.         
  424.     if (
  425.         Q3DisplayGroup_Submit( theCursor3D->fCursorModel, theView)
  426.         == kQ3Failure) goto bail;
  427.     
  428.     return kQ3Success;
  429.     
  430. bail:
  431.     return kQ3Failure;
  432. }
  433.  
  434.  
  435. /*===========================================================================*\
  436.  *
  437.  *    Routine:    Cursor3D_ChangeSizeAgainstGroup()
  438.  *
  439.  *    Comments:    Scales the cursor with respect to a model. Useful to change
  440.  *                cursor size depending on what it acts upon.
  441.  *
  442. \*===========================================================================*/
  443.  
  444. TQ3Status    Cursor3D_ChangeSizeAgainstGroup(
  445.     Cursor3DHdl                theCursor3D,
  446.     TQ3DisplayGroupObject    theModel,
  447.     TQ3ViewObject            theView,
  448.     float                    theScale)
  449. {
  450.     TQ3ViewStatus    theViewStatus;
  451.     TQ3BoundingBox    cursorBBox,  groupBBox;
  452.     float            theRatio;
  453.     
  454.     assert(theCursor3D != NULL);
  455.     assert(*theCursor3D != NULL);
  456.     assert(theModel != NULL);
  457.     assert(theView != NULL);
  458.  
  459.     /*
  460.     **    For the purpose of this, we want to enable bounding
  461.     */
  462.     Cursor3D_EnableBounding(theCursor3D);
  463.     
  464.     /*
  465.     **    Get the two bounding boxes
  466.     */
  467.     if (
  468.         Q3View_StartBoundingBox ( theView, kQ3ComputeBoundsExact )
  469.         != kQ3Failure)
  470.     {
  471.         do {
  472.             Q3DisplayGroup_Submit( (**theCursor3D).fCursorModel, theView) ;
  473.         } while(
  474.             (theViewStatus = Q3View_EndBoundingBox( theView, &cursorBBox ))
  475.             == kQ3ViewStatusRetraverse );
  476.     }
  477.  
  478.     /*    
  479.     **    This has to be completed for this routine
  480.     */    
  481.     else goto bail;
  482.     
  483.     
  484.     
  485.     if (
  486.         Q3View_StartBoundingBox ( theView, kQ3ComputeBoundsExact )
  487.         != kQ3Failure)
  488.     {
  489.         do {
  490.             Q3DisplayGroup_Submit( theModel, theView);
  491.         } while(
  492.             (theViewStatus = Q3View_EndBoundingBox( theView, &groupBBox ))
  493.             == kQ3ViewStatusRetraverse );
  494.     }
  495.     /*    
  496.     **    This has to be completed for this routine
  497.     */    
  498.     else goto bail;
  499.     
  500.     
  501.     /*
  502.     **    Make sure there's stuff in it
  503.     */
  504.     if ((cursorBBox.isEmpty == kQ3False) && (groupBBox.isEmpty == kQ3False) ) {
  505.         /*
  506.         **    Compute the ratio
  507.         */
  508.         theRatio = ((Q3Point3D_Distance((const TQ3Point3D *)&groupBBox.min, 
  509.                                         (const TQ3Point3D *)&groupBBox.max))
  510.                                         /
  511.                     (Q3Point3D_Distance((const TQ3Point3D *)&cursorBBox.min, 
  512.                                         (const TQ3Point3D *)&cursorBBox.max)));
  513.     } else goto bail;
  514.     
  515.     /*
  516.     **    We scale it to match the model and then scale it based on
  517.     **    the parameter
  518.     */
  519.     theRatio = theRatio * theScale;
  520.     
  521.     Cursor3D_Scale(theCursor3D, theRatio);
  522.         
  523.     /*
  524.     **    Don't forget to disable it when we are done
  525.     */
  526.     Cursor3D_DisableBounding(theCursor3D);
  527.     return kQ3Success;
  528.     
  529. bail:
  530.     /*
  531.     **    Don't forget to disable it when we are done
  532.     */
  533.     Cursor3D_DisableBounding(theCursor3D);
  534.     return kQ3Failure;
  535.         
  536. }
  537.  
  538.  
  539.  
  540. /******************************************************************************
  541.  **                                                                             **
  542.  **                            PRIVATE FUNCTIONS                                 **
  543.  **                                                                             **
  544.  *****************************************************************************/
  545.  
  546. /*===========================================================================*\
  547.  *
  548.  *    Routine:    Cursor3D_Init()
  549.  *
  550.  *    Comments:    
  551.  *
  552. \*===========================================================================*/
  553.  
  554. static void    Cursor3D_Init(Cursor3DHdl theCursor3D)
  555. {
  556.     assert(theCursor3D != NULL);
  557.     assert(*theCursor3D != NULL);
  558.     
  559.     /*
  560.     **    don't show orientation
  561.     */
  562.     
  563.     (**theCursor3D).fShowOrientation = kQ3False;
  564.     
  565.     /*
  566.     **    no model yet
  567.     */
  568.     
  569.     (**theCursor3D).fCursorModel = NULL;    
  570.                 
  571.     /*
  572.     **    Set up the placement (most likely, the origin)
  573.     */
  574.     
  575.     Cursor3D_InitPlacement(&(**theCursor3D).fCursorPlacement);
  576.     
  577.     /*
  578.     **    no transform
  579.     */
  580.     
  581.     Q3Matrix4x4_SetIdentity(&(**theCursor3D).fTransform);
  582.     
  583.     
  584.     /*
  585.     **    no scale
  586.     */
  587.     
  588.     (**theCursor3D).fScale.x =
  589.     (**theCursor3D).fScale.y =
  590.     (**theCursor3D).fScale.z = 1.0;
  591.     
  592.     /*
  593.     **    no attributes
  594.     */
  595.     
  596.     (**theCursor3D).fCursorAttributeSet = NULL;                
  597. }
  598.  
  599. /*===========================================================================*\
  600.  *
  601.  *    Routine:    Cursor3D_InitPlacement()
  602.  *
  603.  *    Comments:    
  604.  *
  605. \*===========================================================================*/
  606.  
  607. static void    Cursor3D_InitPlacement(Cursor3DPlacement *theCursor3DPlacement)
  608. {
  609.     Q3Point3D_Set(&theCursor3DPlacement->cursorLocation, 0.0, 0.0, 0.0);
  610.     Q3Vector3D_Set(&theCursor3DPlacement->toward, 0.0, 0.0, 1.0);
  611.     Q3Vector3D_Set(&theCursor3DPlacement->up, 0.0, 1.0, 0.0);
  612. }
  613.  
  614.  
  615. /*===========================================================================*\
  616.  *
  617.  *    Routine:    Cursor3D_EnableBounding()
  618.  *
  619.  *    Comments:    
  620.  *
  621. \*===========================================================================*/
  622.  
  623. static void    Cursor3D_EnableBounding(Cursor3DHdl theCursor3D)
  624. {
  625.     TQ3DisplayGroupState    theState;
  626.     
  627.     assert(theCursor3D != NULL);
  628.     assert(*theCursor3D != NULL);
  629.  
  630.     Q3DisplayGroup_GetState((**theCursor3D).fCursorModel, &theState);
  631.     theState = theState | (    kQ3DisplayGroupStateMaskUseBoundingBox |
  632.                             kQ3DisplayGroupStateMaskUseBoundingSphere);
  633.     Q3DisplayGroup_SetState((**theCursor3D).fCursorModel,  theState);
  634.  
  635.     Q3DisplayGroup_GetState((**theCursor3D).fOrientationModel, &theState);
  636.     theState = theState | (    kQ3DisplayGroupStateMaskUseBoundingBox |
  637.                             kQ3DisplayGroupStateMaskUseBoundingSphere);
  638.     Q3DisplayGroup_SetState((**theCursor3D).fOrientationModel,  theState);
  639. }
  640.  
  641.  
  642. /*===========================================================================*\
  643.  *
  644.  *    Routine:    Cursor3D_DisableBounding()
  645.  *
  646.  *    Comments:    
  647.  *
  648. \*===========================================================================*/
  649.  
  650. static void    Cursor3D_DisableBounding(Cursor3DHdl theCursor3D)
  651. {
  652.     TQ3DisplayGroupState    theState;
  653.     
  654.     assert(theCursor3D != NULL);
  655.     assert(*theCursor3D != NULL);
  656.  
  657.     Q3DisplayGroup_GetState((**theCursor3D).fCursorModel, &theState);
  658.     theState = theState & ~(    kQ3DisplayGroupStateMaskUseBoundingBox |
  659.                             kQ3DisplayGroupStateMaskUseBoundingSphere);
  660.     Q3DisplayGroup_SetState((**theCursor3D).fCursorModel,  theState);
  661.  
  662.     Q3DisplayGroup_GetState((**theCursor3D).fOrientationModel, &theState);
  663.     theState = theState & ~(    kQ3DisplayGroupStateMaskUseBoundingBox |
  664.                             kQ3DisplayGroupStateMaskUseBoundingSphere);
  665.     Q3DisplayGroup_SetState((**theCursor3D).fOrientationModel,  theState);
  666. }
  667.  
  668.  
  669. /*===========================================================================*\
  670.  *
  671.  *    Routine:    Cursor3D_Scale()
  672.  *
  673.  *    Comments:    
  674.  *
  675. \*===========================================================================*/
  676.  
  677. static void    Cursor3D_Scale(    Cursor3DHdl    theCursor3D,
  678.                             float        theScale)
  679. {
  680.     assert(theCursor3D != NULL);
  681.     assert(*theCursor3D != NULL);
  682.  
  683.     Q3Vector3D_Set ( &(**theCursor3D).fScale, theScale, theScale, theScale ) ;    
  684.     
  685. }
  686.  
  687.  
  688. /*===========================================================================*\
  689.  *
  690.  *    Routine:    Cursor3D_NewDefaultCursor()
  691.  *
  692.  *    Comments:    Creates the default model for the cursor
  693.  *
  694. \*===========================================================================*/
  695.  
  696. static TQ3DisplayGroupObject    Cursor3D_NewDefaultCursor(void)
  697. {
  698.     TQ3DisplayGroupObject        theModel                = NULL,
  699.                                 thePart                    = NULL;
  700.     TQ3ShaderObject                myIlluminationShader    = NULL;
  701.     TQ3StyleObject                theStyleObject            = NULL;
  702.     
  703.     TQ3ConeData                    theConeData;
  704.     TQ3ColorRGB                    theColor;
  705.     TQ3CylinderData                theCylinderData;
  706.     TQ3SubdivisionStyleData        theSubdivisionStyleData;
  707.     
  708.     theModel = Q3DisplayGroup_New();
  709.  
  710.     /*    
  711.     **    Essential for this function to continue
  712.     */    
  713.     if (!theModel) goto bail;
  714.     
  715.     
  716.     myIlluminationShader = Q3LambertIllumination_New();
  717.     
  718.     if (myIlluminationShader)    {
  719.         Q3Group_AddObject(theModel, myIlluminationShader) ;
  720.         Q3Object_Dispose(myIlluminationShader);
  721.         myIlluminationShader = NULL;
  722.     }
  723.     
  724.     /**************************************
  725.      **                                     **
  726.      **        HOW TO MAKE A PENCIL         **
  727.      **                                     **
  728.      **************************************/
  729.  
  730.     theStyleObject = Q3InterpolationStyle_New(kQ3InterpolationStyleVertex);
  731.     
  732.     if (theStyleObject)    {
  733.         Q3Group_AddObject(theModel, theStyleObject) ;
  734.         Q3Object_Dispose(theStyleObject);
  735.         theStyleObject = NULL;
  736.     }
  737.     
  738.     theSubdivisionStyleData.method = kQ3SubdivisionMethodConstant;
  739.     theSubdivisionStyleData.c1 = 6;
  740.     theSubdivisionStyleData.c2 = 1;
  741.     
  742.     theStyleObject = Q3SubdivisionStyle_New(&theSubdivisionStyleData);
  743.     if (theStyleObject)    {
  744.         Q3Group_AddObject(theModel, theStyleObject) ;
  745.         Q3Object_Dispose(theStyleObject);
  746.         theStyleObject = NULL;
  747.     }
  748.     
  749.     
  750.     /**************************************
  751.      **                                     **
  752.      **            THE GRAPHITE             **
  753.      **                                     **
  754.      **************************************/
  755.  
  756.     Q3Point3D_Set(&theConeData.origin, 0, 0, -1.0);
  757.     Q3Vector3D_Set(&theConeData.orientation, 0, 0, 1.0);
  758.     Q3Vector3D_Set(&theConeData.majorRadius, 0.26, 0.0, 0);
  759.     Q3Vector3D_Set(&theConeData.minorRadius, 0.0, 0.26, 0);
  760.     theConeData.uMin = 0.0; theConeData.uMax = 1.0;
  761.     theConeData.vMin = 0.0; theConeData.vMax = 1.0;
  762.     theConeData.caps =     kQ3EndCapNone;
  763.     theConeData.interiorAttributeSet = NULL;
  764.     theConeData.bottomAttributeSet = NULL;
  765.     theConeData.faceAttributeSet = NULL;
  766.     theConeData.coneAttributeSet = Q3AttributeSet_New() ;
  767.  
  768.     theColor.r = 0.25; theColor.g = 0.25; theColor.b = 0.25;
  769.  
  770.     if (theConeData.coneAttributeSet) {
  771.         Q3AttributeSet_Add (theConeData.coneAttributeSet,
  772.                             kQ3AttributeTypeDiffuseColor,
  773.                             &theColor);
  774.     }
  775.     
  776.     thePart = Q3Cone_New(&theConeData);
  777.     
  778.     if (thePart)    {
  779.         Q3Group_AddObject(theModel, thePart) ;
  780.         Q3Object_Dispose(thePart);
  781.         thePart = NULL;
  782.     }
  783.     
  784.     if (theConeData.coneAttributeSet) {
  785.         Q3Object_Dispose(theConeData.coneAttributeSet);
  786.         theConeData.coneAttributeSet = NULL;
  787.     }
  788.     
  789.     /**************************************
  790.      **                                     **
  791.      **            THE WOOD                 **
  792.      **                                     **
  793.      **************************************/
  794.  
  795.     Q3Point3D_Set(&theConeData.origin, 0, 0, -2.0);
  796.     Q3Vector3D_Set(&theConeData.orientation, 0, 0, 2.0);
  797.     Q3Vector3D_Set(&theConeData.majorRadius, 0.5, 0.0, 0);
  798.     Q3Vector3D_Set(&theConeData.minorRadius, 0.0, 0.5, 0);
  799.     theConeData.uMin = 0.0; theConeData.uMax = 1.0;
  800.     theConeData.vMin = 0.0; theConeData.vMax = 1.0;
  801.     theConeData.caps =     kQ3EndCapNone;
  802.     theConeData.interiorAttributeSet = NULL;
  803.     theConeData.bottomAttributeSet = NULL;
  804.     theConeData.faceAttributeSet = NULL;
  805.     theConeData.coneAttributeSet = Q3AttributeSet_New() ;
  806.  
  807.     theColor.r = 0.75; theColor.g = 0.75; theColor.b = 0.25;
  808.  
  809.     if (theConeData.coneAttributeSet) {
  810.         Q3AttributeSet_Add (theConeData.coneAttributeSet,
  811.                             kQ3AttributeTypeDiffuseColor,
  812.                             &theColor);
  813.     }
  814.                             
  815.     thePart = Q3Cone_New(&theConeData);
  816.  
  817.     if (thePart)    {
  818.         Q3Group_AddObject(theModel, thePart) ;
  819.         Q3Object_Dispose(thePart);
  820.         thePart = NULL;
  821.     }
  822.     
  823.     if (theConeData.coneAttributeSet) {
  824.         Q3Object_Dispose(theConeData.coneAttributeSet);
  825.         theConeData.coneAttributeSet = NULL;
  826.     }
  827.     
  828.         
  829.     /**************************************
  830.      **                                     **
  831.      **            THE ERASER                 **
  832.      **                                     **
  833.      **************************************/
  834.     
  835.     theSubdivisionStyleData.method = kQ3SubdivisionMethodConstant;
  836.     theSubdivisionStyleData.c1 = 12;
  837.     theSubdivisionStyleData.c2 = 1;
  838.  
  839.     theStyleObject = Q3SubdivisionStyle_New(&theSubdivisionStyleData);
  840.     
  841.     if (theStyleObject)    {
  842.         Q3Group_AddObject(theModel, theStyleObject) ;
  843.         Q3Object_Dispose(theStyleObject);
  844.         theStyleObject = NULL;
  845.     }
  846.     
  847.     Q3Point3D_Set(&theCylinderData.origin, 0, 0, -7.0);
  848.     Q3Vector3D_Set(&theCylinderData.orientation, 0, 0, 1.0);
  849.     Q3Vector3D_Set(&theCylinderData.majorRadius, 0.48, 0.0, 0);
  850.     Q3Vector3D_Set(&theCylinderData.minorRadius, 0.0, 0.48, 0);
  851.     theCylinderData.uMin = 0.0; theCylinderData.uMax = 1.0;
  852.     theCylinderData.vMin = 0.0; theCylinderData.vMax = 1.0;
  853.     theCylinderData.caps =     kQ3EndCapMaskBottom;
  854.     theCylinderData.interiorAttributeSet = NULL;
  855.     theCylinderData.topAttributeSet = NULL;
  856.     theCylinderData.bottomAttributeSet = NULL;
  857.     theCylinderData.faceAttributeSet = NULL;
  858.     theCylinderData.cylinderAttributeSet = Q3AttributeSet_New() ;
  859.  
  860.     theColor.r = 1.0; theColor.g = 0.5; theColor.b = 0.5;
  861.  
  862.     if (theCylinderData.cylinderAttributeSet) {
  863.         Q3AttributeSet_Add (theCylinderData.cylinderAttributeSet,
  864.                             kQ3AttributeTypeDiffuseColor,
  865.                             &theColor);
  866.     }
  867.     
  868.     thePart = Q3Cylinder_New(&theCylinderData);
  869.     
  870.     if (thePart)    {
  871.         Q3Group_AddObject(theModel, thePart) ;
  872.         Q3Object_Dispose(thePart);
  873.         thePart = NULL;
  874.     }
  875.     
  876.     if (theCylinderData.cylinderAttributeSet) {
  877.         Q3Object_Dispose(theCylinderData.cylinderAttributeSet);
  878.         theCylinderData.cylinderAttributeSet = NULL;
  879.     }
  880.         
  881.     /**************************************
  882.      **                                     **
  883.      **            THE YELLOW PAINT         **
  884.      **                                     **
  885.      **************************************/
  886.  
  887.     theSubdivisionStyleData.method = kQ3SubdivisionMethodConstant;
  888.     theSubdivisionStyleData.c1 = 6;
  889.     theSubdivisionStyleData.c2 = 1;
  890.     
  891.     theStyleObject = Q3SubdivisionStyle_New(&theSubdivisionStyleData);
  892.     if (theStyleObject)    {
  893.         Q3Group_AddObject(theModel, theStyleObject) ;
  894.         Q3Object_Dispose(theStyleObject);
  895.         theStyleObject = NULL;
  896.     }
  897.     
  898.     theStyleObject = Q3InterpolationStyle_New(kQ3InterpolationStyleNone);
  899.     if (theStyleObject)    {
  900.         Q3Group_AddObject(theModel, theStyleObject) ;
  901.         Q3Object_Dispose(theStyleObject);
  902.         theStyleObject = NULL;
  903.     }
  904.     
  905.     Q3Point3D_Set(&theCylinderData.origin, 0, 0, -6.0);
  906.     Q3Vector3D_Set(&theCylinderData.orientation, 0, 0, 4.0);
  907.     Q3Vector3D_Set(&theCylinderData.majorRadius, 0.5, 0.0, 0);
  908.     Q3Vector3D_Set(&theCylinderData.minorRadius, 0.0, 0.5, 0);
  909.     theCylinderData.uMin = 0.0; theCylinderData.uMax = 1.0;
  910.     theCylinderData.vMin = 0.0; theCylinderData.vMax = 1.0;
  911.     theCylinderData.caps =     kQ3EndCapNone;
  912.     theCylinderData.interiorAttributeSet = NULL;
  913.     theCylinderData.topAttributeSet = NULL;
  914.     theCylinderData.bottomAttributeSet = NULL;
  915.     theCylinderData.faceAttributeSet = NULL;
  916.     theCylinderData.cylinderAttributeSet = Q3AttributeSet_New() ;
  917.  
  918.     theColor.r = 1.0; theColor.g = 1.0; theColor.b = 0.0;
  919.  
  920.     if (theCylinderData.cylinderAttributeSet) {
  921.         Q3AttributeSet_Add (theCylinderData.cylinderAttributeSet,
  922.                             kQ3AttributeTypeDiffuseColor,
  923.                             &theColor);
  924.     }
  925.                             
  926.     thePart = Q3Cylinder_New(&theCylinderData);
  927.     
  928.     if (thePart)    {
  929.         Q3Group_AddObject(theModel, thePart) ;
  930.         Q3Object_Dispose(thePart);
  931.         thePart = NULL;
  932.     }
  933.     
  934.     if (theCylinderData.cylinderAttributeSet) {
  935.         Q3Object_Dispose(theCylinderData.cylinderAttributeSet);
  936.         theCylinderData.cylinderAttributeSet = NULL;
  937.     }    
  938.     
  939.     return    theModel;
  940.     
  941. bail:
  942.     return NULL;    
  943. }
  944.  
  945.  
  946. /*===========================================================================*\
  947.  *
  948.  *    Routine:    Cursor3D_NewDefaultOrientationModel()
  949.  *
  950.  *    Comments:    Creates the default orientation model
  951.  *
  952. \*===========================================================================*/
  953.  
  954. static TQ3DisplayGroupObject    Cursor3D_NewDefaultOrientationModel(void)
  955. {
  956.     TQ3DisplayGroupObject    theModel                = NULL,
  957.                             theLine                    = NULL;
  958.     TQ3ShaderObject            myIlluminationShader    = NULL;
  959.     
  960.     TQ3ColorRGB                theColor;
  961.     TQ3LineData                theLineData;
  962.     
  963.  
  964.     /*    
  965.     **    theZOffsetAmount is needed to raise the lines alightly above the
  966.     **    surface of what ever you're drawing on. Needed because if the lines
  967.     **    were directly on the surface, they would disappear.
  968.     */    
  969.         
  970.     const float                theZOffsetAmount        = -0.1;
  971.  
  972.  
  973.     theModel = Q3DisplayGroup_New();
  974.     
  975.     /*    
  976.     **    Essential for this function to continue
  977.     */    
  978.     if (!theModel) goto bail;
  979.     
  980.     myIlluminationShader = Q3LambertIllumination_New();
  981.     
  982.     if (myIlluminationShader)    {
  983.         Q3Group_AddObject(theModel, myIlluminationShader) ;
  984.         Q3Object_Dispose(myIlluminationShader);
  985.         myIlluminationShader = NULL;
  986.     }
  987.     
  988.     /**************************************
  989.      **                                     **
  990.      **            HOW TO CREATE             **
  991.      **            3 SIMPLE LINES             **
  992.      **                                     **
  993.      **************************************/
  994.     
  995.     /*
  996.     **    The x, y, and z axis are colored r, g and b, respectively
  997.     */
  998.     
  999.     /**************************************
  1000.      **                                     **
  1001.      **                X AXIS                 **
  1002.      **                                     **
  1003.      **************************************/
  1004.  
  1005.     theLineData.vertices[0].point.x            = 0;
  1006.     theLineData.vertices[0].point.y            = 0;
  1007.     theLineData.vertices[0].point.z            = theZOffsetAmount;
  1008.     theLineData.vertices[0].attributeSet    = NULL ;
  1009.     
  1010.     theLineData.vertices[1].point.x            = 2.0;
  1011.     theLineData.vertices[1].point.y            = 0.0;
  1012.     theLineData.vertices[1].point.z            = theZOffsetAmount;
  1013.     theLineData.vertices[1].attributeSet    = NULL ;
  1014.     
  1015.     theColor.r                = 1.0;
  1016.     theColor.g = theColor.b = 0.75; 
  1017.     
  1018.     theLineData.lineAttributeSet = Q3AttributeSet_New() ;
  1019.     
  1020.     if (theLineData.lineAttributeSet) {
  1021.         Q3AttributeSet_Add (theLineData.lineAttributeSet,
  1022.                             kQ3AttributeTypeDiffuseColor,
  1023.                             &theColor);
  1024.     }
  1025.     
  1026.     theLine = Q3Line_New(&theLineData);
  1027.     
  1028.     if (theLine)    {
  1029.         Q3Group_AddObject(theModel, theLine) ;
  1030.         Q3Object_Dispose(theLine);
  1031.         theLine = NULL;
  1032.     }
  1033.     
  1034.     if (theLineData.lineAttributeSet) {
  1035.         Q3Object_Dispose(theLineData.lineAttributeSet);
  1036.         theLineData.lineAttributeSet = NULL;
  1037.     }
  1038.     
  1039.     
  1040.     /**************************************
  1041.      **                                     **
  1042.      **                Y AXIS                 **
  1043.      **                                     **
  1044.      **************************************/
  1045.      
  1046.     theLineData.vertices[0].point.x            = 0;
  1047.     theLineData.vertices[0].point.y            = 0;
  1048.     theLineData.vertices[0].point.z            = theZOffsetAmount;
  1049.     theLineData.vertices[0].attributeSet    = NULL ;
  1050.     
  1051.     theLineData.vertices[1].point.x            = 0.0;
  1052.     theLineData.vertices[1].point.y            = 2.0;
  1053.     theLineData.vertices[1].point.z            = theZOffsetAmount;
  1054.     theLineData.vertices[1].attributeSet    = NULL ;
  1055.     
  1056.  
  1057.     theColor.g                = 1.0;
  1058.     theColor.r = theColor.b = 0.75; 
  1059.     
  1060.     theLineData.lineAttributeSet = Q3AttributeSet_New();
  1061.     
  1062.     if (theLineData.lineAttributeSet) {
  1063.         Q3AttributeSet_Add (theLineData.lineAttributeSet,
  1064.                             kQ3AttributeTypeDiffuseColor,
  1065.                             &theColor);
  1066.     }
  1067.                             
  1068.     theLine = Q3Line_New(&theLineData);
  1069.     
  1070.     if (theLine)    {
  1071.         Q3Group_AddObject(theModel, theLine) ;
  1072.         Q3Object_Dispose(theLine);
  1073.         theLine = NULL;
  1074.     }
  1075.     
  1076.     if (theLineData.lineAttributeSet) {
  1077.         Q3Object_Dispose(theLineData.lineAttributeSet);
  1078.         theLineData.lineAttributeSet = NULL;
  1079.     }
  1080.     
  1081.     /**************************************
  1082.      **                                     **
  1083.      **                Z AXIS                 **
  1084.      **                                     **
  1085.      **************************************/
  1086.  
  1087.     theLineData.vertices[0].point.x            = 0;
  1088.     theLineData.vertices[0].point.y            = 0;
  1089.     theLineData.vertices[0].point.z            = theZOffsetAmount;
  1090.     theLineData.vertices[0].attributeSet    = NULL ;
  1091.     
  1092.     theLineData.vertices[1].point.x            = 0.0;
  1093.     theLineData.vertices[1].point.y            = 0.0;
  1094.     theLineData.vertices[1].point.z            = -2.0;
  1095.     theLineData.vertices[1].attributeSet    = NULL ;
  1096.     
  1097.     theColor.b                = 1.0;
  1098.     theColor.g = theColor.r = 0.75; 
  1099.  
  1100.     theLineData.lineAttributeSet = Q3AttributeSet_New();
  1101.     
  1102.     if (theLineData.lineAttributeSet) {
  1103.         Q3AttributeSet_Add (theLineData.lineAttributeSet,
  1104.                             kQ3AttributeTypeDiffuseColor,
  1105.                             &theColor);
  1106.     }
  1107.                             
  1108.     theLine = Q3Line_New(&theLineData);
  1109.     
  1110.     if (theLine)    {
  1111.         Q3Group_AddObject(theModel, theLine) ;
  1112.         Q3Object_Dispose(theLine);
  1113.         theLine = NULL;
  1114.     }
  1115.     
  1116.     if (theLineData.lineAttributeSet) {
  1117.         Q3Object_Dispose(theLineData.lineAttributeSet);
  1118.         theLineData.lineAttributeSet = NULL;
  1119.     }
  1120.     
  1121.     return    theModel;
  1122.     
  1123. bail:
  1124.     return NULL;
  1125. }
  1126.